package xyz.thetbw.autocode.utils

import xyz.thetbw.autocode.Config
import xyz.thetbw.autocode.DataModel
import mu.KotlinLogging
import java.sql.Connection
import java.sql.DriverManager
import kotlin.system.exitProcess

private val logger  = KotlinLogging.logger {  }

object SqlUtils{

    init {
        //java 的 SPI 会自动加载实现，这里不需要手动注册驱动
        //Class.forName("com.mysql.cj.jdbc.Driver").newInstance()
    }


    /**
     * 获取mysql连接
     */
    private fun getConnection():Connection = DriverManager.getConnection(
        Config.instance.dataSource.url,
        Config.instance.dataSource.username,
        Config.instance.dataSource.password
    )

    //获取数据库的描述model
    fun getDataModel(): DataModel {
        val connection = getConnection()
        val dataModel = DataModel()
        dataModel.database = "nothing"
        dataModel.table = Config.instance.useTable

        connection.use{
            dataModel.tableComment = getTableComment(connection,Config.instance.useTable)


            checkTableExits(connection,Config.instance.useTable)
            val sql = "show full columns from ${Config.instance.useTable}"
            val stem =  connection.prepareStatement(sql)
            stem.use {
                val result = stem.executeQuery()
                val tableFields = ArrayList<DataModel.DataField>()
                result.use {
                    while (result.next()){
                        val dataField = DataModel.DataField().apply {
                            name = result.getString("Field")
                            val typeText = result.getString("Type")
                            val dataType = DataModel.DataFieldType.getBySqlType(typeText.split("(")[0])
                            type = dataType ?: run {
                                logger.error { "不支持该字段类型: $typeText" }
                                exitProcess(1)
                            }
                            nullable  = result.getString("Null") == "Yes"
                            comment  = result.getString("Comment")
                            if (typeText.contains('(')){
                                val startPos = typeText.indexOfFirst { '(' == it }
                                val commaPos = typeText.substring(startPos+1).indexOfFirst { ',' == it }
                                val endPos = typeText.indexOfLast { ')' == it }
                                length  = typeText.substring(startPos+1,if (commaPos == -1) endPos else commaPos+startPos+1).toInt()
                            }
                        }
                        tableFields.add(dataField)
                    }
                }
                dataModel.dataFields = tableFields
            }
        }
        return dataModel
    }

    //获取表备注
    private fun getTableComment(connection: Connection,tableName: String): String {
        val sql =  "SELECT TABLE_COMMENT FROM information_schema.tables WHERE table_name = '${tableName}'"
        val stem = connection.prepareStatement(sql)
        stem.use {
            val result = stem.executeQuery()
            result.use {
                result.next()
                return result.getString(1)
            }
        }
    }

    private fun checkTableExits(connection: Connection,tableName: String){
        val metadata = connection.metaData
        if (metadata == null){
            logger.error { "获取数据库描述信息失败" }
            exitProcess(1)
        }
        val table = metadata.getTables(null,null,null, arrayOf("TABLE"))
        while (table.next()){
            if (table.getString(3) == tableName){
                return
            }
        }
        logger.warn { "没有找到当前表：$tableName" }
        exitProcess(1)
    }

}